﻿using System;
using System.Collections.Generic;
using System.Linq;
using CID.Domain.Development;
using CID.Domain.Operations;

namespace CID.Execution.Controller.Support
{
    sealed class AffectedVersionsResolver
    {
        private IEnumerable<IVersion> affectedVersions;

        public IRelease Release { get; private set; }

        public IEnvironment Environment { get; private set; }

        public AffectedVersionsResolver(IRelease release, IEnvironment environment)
        {
            Release = release;
            Environment = environment;
            affectedVersions = ResolveAffectedVersions();
        }

        public IEnumerable<IVersion> GetAffectedVersions()
        {
            return affectedVersions;
        }

        private IEnumerable<IVersion> ResolveAffectedVersions()
        {
            var result = new List<IVersion>();
            result.AddRange(Release.Versions);
            var releasedComponentIds = result.Select(x => x.Component.Id).ToArray();
            var versionsToAnalize = Environment.ActiveVersions.Select(x => x.Version).Where(x => !releasedComponentIds.Contains(x.Component.Id)).ToList();
            int analizedAndNotImpactedVersionsCount, versionsToAnalizeCount;

            do
            {
                analizedAndNotImpactedVersionsCount = 0;
                versionsToAnalizeCount = versionsToAnalize.Count;
                for (int i = versionsToAnalize.Count - 1; i >= 0; i--)
                {
                    var versionToAnalize = versionsToAnalize[i];
                    if (versionToAnalize.DependsOn.Count(x => result.Select(y => y.Component.Id).Contains(x.Id)) > 0)
                    {
                        versionsToAnalize.Remove(versionToAnalize);
                        result.Add(versionToAnalize);
                    }
                    else
                        analizedAndNotImpactedVersionsCount++;
                }
            }
            while (analizedAndNotImpactedVersionsCount != versionsToAnalizeCount);

            return result;
        }

        
    }
}
